package state;

import iplayparticle.view.iplayparticleResources;

import java.util.Vector;

import state.font.FontManager;
import state.font.ImageText;
import state.util.GameColor;
import state.util.NumberUtil;
import state.util.array.ObjectArray;
import state.util.array.StringArray;

public class GameAlert extends GameForm implements TimerListener, TouchScreenListener {
  /** Kiểu Alert với 1 nút OK */
  public static final byte OK_TYPE = 0;

  /** Kiểu Alert với 2 nút Yes và No */
  public static final byte YES_NO_TYPE = 1;

  /** Alert kiểu loading form */
  public static final byte LOADING_FORM = 2;

  /** Alert kiểu loading và có nút cancel để dừng xử lý loading */
  public static final byte LOADING_WITH_CANCEL_BUTTON_TYPE = 3;

  /** Alert kiểu có danh sách các nút do người dùng quyết định */
  private final byte CUSTOM_BUTTON_TYPE = 4;

  /** Alert kiểu cho phép người dùng input number */
  public static final byte INPUT_NUMBER_TYPE = 5;

  /** Alert kiểu cho phép người dùng config table */
  public static final byte CUSTOM_UI_TYPE = 6;

  /** Alert kiểu loading và không có button */
  public static final byte LOADING_WITH_NO_BUTTON_TYPE = 7;

  /** Sắp xếp ngang */
  public static final byte HORIZONTAL_ALINE = 0;

  /** Sắp xếp dọc */
  public static final byte VERTICAL_ALINE = 1;

  public static final byte BUTTON_WIDTH_SMALL = 0;
  public static final byte BUTTON_WIDTH_LARGE = 1;

  public static final byte ALERT_ID_NOT_DEFINE = -1;
  public static final byte OK_BUTTON = 0;
  public static final byte YES_BUTTON = 1;
  public static final byte NO_BUTTON = 2;
  public static final byte LOADING_DONE_EVENT = 3;
  public static final byte CANCEL_BUTTON = 4;

  private final byte MAX_NUMBER_LEN = 5;
  private final byte BUTTON_DISTANCE_HORIZONTAL = 15;
  private final byte BUTTON_DISTANCE_VERTICAL = 5;

  private ObjectArray buttonSprites = null;

  private GameImage bgImage = null;
  private GameImage buttonImage = null;
  private GameImage focusedButtonImage = null;
  private GameImage loadingImage1 = null;
  private GameImage loadingImage2 = null;
  private GameImage bgLoadingImage = null;
  private GameImage buttonSmallImage = null;
  private GameImage buttonSmallFocusImage = null;
  private GameImage buttonLargeImage = null;
  private GameImage buttonLargeFocusImage = null;

  private int alertType = 0;
  private Vector alertMessages = null;
  private int alertId = 0;
  private GameForm parent = null;
  private StringArray buttonLabels = null;
  private int alineType = 0;

  private int buttonIndex = 0;
  private int alertX = 0;
  private int alertY = 0;
  private int messageY = 0;
  private ImageText vnText = null;
  private int buttonWidth = 0;
  private boolean isAutoHideInEvent = false;
  private int count = 0;
  private AlertListener listenner = null;
  private GameForm customeUI = null;
  private int alertTimeOut = Integer.MAX_VALUE;

  private static GameAlert inst = null;

  protected GameAlert() {
    alertMessages = new Vector();
  }

  public GameForm create() {
    return new GameAlert();
  }

  public static GameForm instance() {
    if (inst == null) {
      inst = new GameAlert();
    }
    return inst;
  }

  public GameAlert setListenner(AlertListener listenner1) {
    this.listenner = listenner1;
    return this;
  }

  /**
   * Hiển thị Alert OK
   * 
   * @param alertMessage - chuỗi thông báo, bằng null hoặc empty nếu không có message
   */
  public GameAlert alert(String alertMessage) {
    return showAlert(null, GameAlert.OK_TYPE, alertMessage);
  }

  /**
   * Hiển thị Alert OK
   * 
   * @param alertMessage - chuỗi thông báo, bằng null hoặc empty nếu không có message
   */
  public GameAlert alert1(StringArray alertMessage) {
    return showAlert3(null, GameAlert.OK_TYPE, alertMessage);
  }

  /**
   * Hiển thị Alert
   * 
   * @param parent - State hiển thị nền
   * @param listenner1 - Listener để handle sự kiện Alert, bằng null nếu sự kiện trả về cho parent
   * @param alertType1 - Kiểu Alert
   * @param alertMessage - chuỗi thông báo, bằng null hoặc empty nếu không có message
   */
  public GameAlert showAlert(AlertListener listenner1, byte alertType1, String alertMessage) {
    return showAlert2(listenner1, alertType1, alertMessage, 0);
  }

  /**
   * Hiển thị Alert
   * 
   * @param parent - State hiển thị nền
   * @param listenner1 - Listener để handle sự kiện Alert, bằng null nếu sự kiện trả về cho parent
   * @param alertType1 - Kiểu Alert
   * @param alertMessage - chuỗi thông báo, bằng null hoặc empty nếu không có message
   * @param alertId1 - Id cho lần gọi alert này, dùng để nhận biết cho hàm alertEventPerform trả về cho State. Giá trị của alertId do người dùng thiết lập.
   */
  public GameAlert showAlert2(AlertListener listenner1, byte alertType1, String alertMessage, int alertId1) {
    return showAlert1(listenner1, alertType1, new StringArray(new String[] { alertMessage }, 1), alertId1);
  }

  /**
   * Hiển thị Alert
   * 
   * @param parent - State hiển thị nền
   * @param listenner1 - Listener để handle sự kiện Alert, bằng null nếu sự kiện trả về cho parent
   * @param alertType1 - Kiểu Alert
   * @param alertMessages1 - mảng chuỗi thông báo, bằng null hoặc empty nếu không có message nào
   */
  public GameAlert showAlert3(AlertListener listenner1, byte alertType1, StringArray alertMessages1) {
    return showAlert1(listenner1, alertType1, alertMessages1, 0);
  }

  /**
   * Hiển thị Alert
   * 
   * @param parent - State hiển thị nền
   * @param listenner1 - Listener để handle sự kiện Alert, bằng null nếu sự kiện trả về cho parent
   * @param alertType1 - Kiểu Alert
   * @param alertMessages1 - mảng chuỗi thông báo, bằng null hoặc empty nếu không có message nào
   * @param alertId1 - Id cho lần gọi alert này, dùng để nhận biết cho hàm alertEventPerform trả về cho State. Giá trị của alertId do người dùng thiết lập.
   */
  public GameAlert showAlert1(AlertListener listenner1, byte alertType1, StringArray alertMessages1, int alertId1) {
    this.alertType = alertType1;
    this.parent = findParent();

    if (listenner1 == null) {
      this.listenner = parent;
    } else {
      this.listenner = listenner1;
    }

    this.alertId = alertId1;
    this.alertMessages.removeAllElements();
    if (alertMessages1 != null) {
      for (int i = 0; i < alertMessages1.len(); i++) {
        this.alertMessages.addElement(alertMessages1.get(i));
      }
    }
    return showAlertPrivate();
  }

  /**
   * Hiển thị Alert với danh sách các nút do người dùng quyết định
   * 
   * @param parent - State hiển thị nền
   * @param listenner1 - Listener để handle sự kiện Alert, bằng null nếu sự kiện trả về cho parent
   * @param buttonLabels1 - Danh sách các nút cần hiển thị
   * @param buttonWidth1 - Kiểu chiều rộng của mỗi button
   * @param alertMessages1 - Mảng chuỗi thông báo, bằng null hoặc empty nếu không có message nào
   * @param alertId1 - Id cho lần gọi alert này, dùng để nhận biết cho hàm alertEventPerform trả về cho State. Giá trị của alertId do người dùng thiết lập.
   * @param alineType1 - Kiểu sắp xếp ngang hay dọc (HORIZONTAL_ALINE hoặc VERTICAL_ALINE)
   */
  public GameAlert showCustomButtonAlert1(AlertListener listenner1, StringArray buttonLabels1, byte buttonWidth1, StringArray alertMessages1, int alertId1, byte alineType1) {
    this.alertType = CUSTOM_BUTTON_TYPE;
    this.parent = findParent();

    if (listenner1 == null) {
      this.listenner = parent;
    } else {
      this.listenner = listenner1;
    }

    this.alertMessages.removeAllElements();
    if (alertMessages1 != null) {
      for (int i = 0; i < alertMessages1.len(); i++) {
        this.alertMessages.addElement(alertMessages1.get(i));
      }
    }
    this.alertId = alertId1;
    this.buttonLabels = buttonLabels1;
    this.alineType = alineType1;
    this.buttonWidth = buttonWidth1;
    return showAlertPrivate();
  }

  /**
   * Hiển thị Alert với danh sách các nút do người dùng quyết định
   * 
   * @param parent - State hiển thị nền
   * @param listenner1 - Listener để handle sự kiện Alert, bằng null nếu sự kiện trả về cho parent
   * @param buttonLabels1 - Danh sách các nút cần hiển thị
   * @param buttonWidth1 - Kiểu chiều rộng của mỗi button
   * @param alertMessage1 - Chuỗi thông báo, bằng null hoặc empty nếu không có message
   * @param alertId1 - Id cho lần gọi alert này, dùng để nhận biết cho hàm alertEventPerform trả về cho State. Giá trị của alertId do người dùng thiết lập.
   * @param alineType1 - Kiểu sắp xếp ngang hay dọc (HORIZONTAL_ALINE hoặc VERTICAL_ALINE)
   */
  public GameAlert showCustomButtonAlert(AlertListener listenner1, StringArray buttonLabels1, byte buttonWidth1, String alertMessage1, int alertId1, byte alineType1) {
    this.alertType = CUSTOM_BUTTON_TYPE;
    this.parent = findParent();

    if (listenner1 == null) {
      this.listenner = parent;
    } else {
      this.listenner = listenner1;
    }

    this.alertMessages.removeAllElements();
    if (alertMessage1 != null) {
      this.alertMessages.addElement(alertMessage1);
    }
    this.alertId = alertId1;
    this.buttonLabels = buttonLabels1;
    this.alineType = alineType1;
    this.buttonWidth = buttonWidth1;
    return showAlertPrivate();
  }

  public GameAlert showCustomUIAlert(GameForm customeUI1, int alertId1) {
    this.alertType = CUSTOM_UI_TYPE;
    this.customeUI = customeUI1;
    customeUI1.isRunning = true;
    customeUI1.init(null);

    this.parent = findParent();

    this.alertId = alertId1;
    return showAlertPrivate();
  }

  private GameForm findParent() {
    GameForm parent1 = GameGlobal.systemCanvas.frmCurrent;
    if (parent1 == this) {
      return this.parent;
    }
    return parent1;
  }

  public boolean isShowing() {
    return GameGlobal.systemCanvas.frmCurrent == this;
  }

  public int getAlertType() {
    return alertType;
  }

  public int getAlertId() {
    return alertId;
  }

  private GameAlert showAlertPrivate() {
    _manager.setFillBackgroundColor(false);
    if (alertType != CUSTOM_UI_TYPE) {
      setSize(GameConstants.SCREEN_WIDTH, GameConstants.SCREEN_HEIGHT);
      buttonIndex = 0;
      count = 0;
      if (alertType == INPUT_NUMBER_TYPE) {
        alertMessages.addElement("");
        alertMessages.addElement("");
      }

      messageY = 35;
      switch (alertType) {
      case OK_TYPE:
        buttonWidth = BUTTON_WIDTH_SMALL;
        buttonLabels = new StringArray(new String[]{"Đồng ý"}, 1);
        break;
      case YES_NO_TYPE:
        buttonWidth = BUTTON_WIDTH_SMALL;
        buttonLabels = new StringArray(new String[]{"Đồng ý", "Hủy"}, 2);
        break;
      case LOADING_FORM:
        buttonLabels = StringArray.create(0);
        break;
      case LOADING_WITH_CANCEL_BUTTON_TYPE:
        buttonWidth = BUTTON_WIDTH_SMALL;
        buttonLabels = new StringArray(new String[]{"Dừng"}, 1);
        break;
      case CUSTOM_BUTTON_TYPE:
        if (alineType == VERTICAL_ALINE) {
          messageY = 11;
        }
        break;
      case INPUT_NUMBER_TYPE:
        alertId = 0;
        buttonLabels = new StringArray(new String[]{"Đồng ý"}, 1);
        break;
      }

      loadImage();
      alertX = (GameConstants.SCREEN_WIDTH - bgImage.getWidth()) / 2;
      alertY = (GameConstants.SCREEN_HEIGHT - bgImage.getHeight()) / 2;
      vnText = FontManager.getFont(FontManager.FONT_SIZE_8);

      switch (alertType) {
      case OK_TYPE:
      case YES_NO_TYPE:
      case LOADING_WITH_CANCEL_BUTTON_TYPE:
      case INPUT_NUMBER_TYPE:
        createHorizontalButtons();
        break;
      case CUSTOM_BUTTON_TYPE:
        if (alineType == HORIZONTAL_ALINE) {
          createHorizontalButtons();
        } else if (alineType == VERTICAL_ALINE) {
          createVerticalButtons();
        }
        break;
      }
    }

    setTimerListener(this);
    isRunning = true;
    GameGlobal.systemCanvas.changeHandleToAlert();
    return this;
  }

  private void loadImage() {
    bgImage = (bgImage == null) ? new GameImage(iplayparticleResources.image_bg_popup, null, null).setStatic(true) : bgImage;
    if (buttonWidth == BUTTON_WIDTH_SMALL) {
      buttonImage = (buttonSmallImage == null) ? buttonSmallImage = new GameImage(iplayparticleResources.image_button_nho, null, null).setStatic(true) : buttonSmallImage;
      focusedButtonImage = (buttonSmallFocusImage == null) ? buttonSmallFocusImage = new GameImage(iplayparticleResources.image_button_nho_focus, null, null).setStatic(true) : buttonSmallFocusImage;
    } else {
      buttonImage = (buttonLargeImage == null) ? buttonLargeImage = new GameImage(iplayparticleResources.image_button_to, null, null).setStatic(true) : buttonLargeImage;
      focusedButtonImage = (buttonLargeFocusImage == null) ? buttonLargeFocusImage = new GameImage(iplayparticleResources.image_button_to_focus, null, null).setStatic(true) : buttonLargeFocusImage;
    }

    if ((alertType == LOADING_FORM) || (alertType == LOADING_WITH_CANCEL_BUTTON_TYPE)) {
      loadingImage1 = (loadingImage1 == null) ? new GameImage(iplayparticleResources.image_loading_1, null, null).setStatic(true) : loadingImage1;
      loadingImage2 = (loadingImage2 == null) ? new GameImage(iplayparticleResources.image_loading_2, null, null).setStatic(true) : loadingImage2;
    } else if (alertType == LOADING_WITH_NO_BUTTON_TYPE) {
      loadingImage1 = (loadingImage1 == null) ? new GameImage(iplayparticleResources.image_loading_1, null, null).setStatic(true) : loadingImage1;
      loadingImage2 = (loadingImage2 == null) ? new GameImage(iplayparticleResources.image_loading_2, null, null).setStatic(true) : loadingImage2;
      bgLoadingImage = (bgLoadingImage == null) ? new GameImage(iplayparticleResources.image_bg_loading, null, null).setStatic(true) : bgLoadingImage;
    }
  }

  /**
   * Lấy State hiển thị nền của Alert
   * 
   * @return State là parent của Alert
   */
  public GameForm getParent() {
    return parent;
  }

  public void doTask() {
    count++;
    if (alertType == LOADING_WITH_NO_BUTTON_TYPE && count >= alertTimeOut) {
      GameGlobal.systemCanvas.hideAlert();
      listenner.alertEventPerform(alertType, 0, alertId); // Khi timeout thì báo lại sự kiện ra ngoài
    }
  }

  public void draw(Graphics g) {
    if (alertType != CUSTOM_UI_TYPE) {
      g.setClip(0, 0, GameConstants.SCREEN_WIDTH, GameConstants.SCREEN_HEIGHT);
    }

    // Vẽ nền
    if ((alertType == LOADING_FORM) || (alertType == LOADING_WITH_CANCEL_BUTTON_TYPE)) {
      g.setColor(0x4F0202);
      g.fillRect(0, 0, GameConstants.SCREEN_WIDTH, GameConstants.SCREEN_HEIGHT);
    } else if (alertType == LOADING_WITH_NO_BUTTON_TYPE) {
      parent.updateFullScreen();
    } else if (alertType == CUSTOM_UI_TYPE) {
      parent.updateFullScreen();
    } else {
      parent.updateFullScreen();
      g.drawImage(bgImage, alertX, alertY, GameConstants.TOP_LEFT_ANCHOR);
    }

    if (alertType != CUSTOM_UI_TYPE) {
      // Viết message
      if ((alertType != LOADING_FORM) && (alertType != LOADING_WITH_CANCEL_BUTTON_TYPE) && (alertType != LOADING_WITH_NO_BUTTON_TYPE)) {
        for (int i = 0; i < alertMessages.size(); i++) {
          vnText.drawString2(g, String.valueOf(alertMessages.elementAt(i)), GameColor.WHITE_CODE, GameConstants.SCREEN_WIDTH / 2, alertY + messageY + 16 * i, GameConstants.TOP_HCENTER_ANCHOR);
        }
      }
    }

    // Draw loading bar
    if ((alertType == LOADING_FORM) || (alertType == LOADING_WITH_CANCEL_BUTTON_TYPE)) {
      int index = count % 11;
      int x1 = 0;
      int y1 = 0;
      if (GameConstants.IS_240x320_SCREEN) {
        vnText.drawString2(g, "Đang tải...", GameColor.WHITE_CODE, GameConstants.SCREEN_WIDTH / 2, 264, GameConstants.TOP_HCENTER_ANCHOR);
        x1 = GameConstants.SCREEN_WIDTH / 2 - 58;
        y1 = 247;
      } else {
        vnText.drawString2(g, "Đang tải...", GameColor.WHITE_CODE, GameConstants.SCREEN_WIDTH / 2, 193, GameConstants.TOP_HCENTER_ANCHOR);
        x1 = GameConstants.SCREEN_WIDTH / 2 - 58;
        y1 = 172;
      }

      for (int i = 1; i < 11; i++) {
        if (i <= index) {
          g.drawImage(loadingImage1, x1 + (loadingImage1.getWidth() + 1) * (i - 1), y1, GameConstants.TOP_LEFT_ANCHOR);
        } else {
          g.drawImage(loadingImage2, x1 + (loadingImage1.getWidth() + 1) * (i - 1), y1, GameConstants.TOP_LEFT_ANCHOR);
        }
      }
    } else if (alertType == LOADING_WITH_NO_BUTTON_TYPE) {
      int x1 = 0;
      int index = count % 11;
      g.drawImage(bgLoadingImage, GameConstants.SCREEN_WIDTH / 2, GameConstants.SCREEN_HEIGHT / 2 - 2, GameConstants.CENTER_ANCHOR);
      if (GameConstants.IS_240x320_SCREEN) {
        if (alertMessages.size() > 0) {
          vnText.drawString2(g, String.valueOf(alertMessages.elementAt(0)), GameColor.WHITE_CODE, GameConstants.SCREEN_WIDTH / 2, GameConstants.SCREEN_HEIGHT / 2 + 3, GameConstants.TOP_HCENTER_ANCHOR);
        }
        x1 = GameConstants.SCREEN_WIDTH / 2 - 58;
      } else {
        if (alertMessages.size() > 0) {
          vnText.drawString2(g, String.valueOf(alertMessages.elementAt(0)), GameColor.WHITE_CODE, GameConstants.SCREEN_WIDTH / 2, GameConstants.SCREEN_HEIGHT / 2 + 3, GameConstants.TOP_HCENTER_ANCHOR);
        }
        x1 = GameConstants.SCREEN_WIDTH / 2 - 58;
      }
      for (int i = 1; i < 11; i++) {
        if (i <= index) {
          g.drawImage(loadingImage1, x1 + (loadingImage1.getWidth() + 1) * (i - 1), GameConstants.SCREEN_HEIGHT / 2 - 15, GameConstants.TOP_LEFT_ANCHOR);
        } else {
          g.drawImage(loadingImage2, x1 + (loadingImage1.getWidth() + 1) * (i - 1), GameConstants.SCREEN_HEIGHT / 2 - 15, GameConstants.TOP_LEFT_ANCHOR);
        }
      }
    } else if (alertType == INPUT_NUMBER_TYPE) { // Draw Input text field
      g.setColor(GameColor.WHITE_CODE);
      g.fillRect(GameConstants.SCREEN_WIDTH / 2 - 50, alertY + 15 + (alertMessages.size() - 2) * 20, 100, 18);
      vnText.drawString2(g, String.valueOf(alertId), GameColor.BLUE_CODE, GameConstants.SCREEN_WIDTH / 2 - 48, alertY + 13 + (alertMessages.size() - 2) * 20, GameConstants.TOP_LEFT_ANCHOR);
      vnText.drawString2(g, "Xóa", GameColor.WHITE_CODE, GameConstants.SCREEN_WIDTH - 10, alertY - 5 + alertMessages.size() * 20, GameConstants.TOP_RIGHT_ANCHOR);
    } else if (alertType == CUSTOM_UI_TYPE) {
      if (customeUI != null) {
        customeUI.updateFullScreen();
      }
    }
  }

  private void createHorizontalButtons() {
    if (buttonLabels == null) {
      return;
    }
    int leftX = (GameConstants.SCREEN_WIDTH - buttonImage.getWidth() * buttonLabels.len() - (buttonLabels.len() - 1) * BUTTON_DISTANCE_HORIZONTAL) / 2;
    int x1 = leftX;

    buttonSprites = ObjectArray.create(buttonLabels.len());
    for (int i = 0; i < buttonLabels.len(); i++) {
      buttonSprites.set(i, new Sprite(buttonImage, _manager, x1, alertY + 100, GameConstants.TOP_LEFT_ANCHOR));
      final int index = i;
      ((Sprite) buttonSprites.get(i)).setDrawListener(new DrawListener() {
        public void paint(Sprite source, Graphics g) {
          vnText.drawString2(g, buttonLabels.get(index), GameColor.WHITE_CODE, source.getRealX() + buttonImage.getWidth() / 2, alertY + 100 + buttonImage.getHeight() / 2, GameConstants.CENTER_ANCHOR);
        }
      });
      ((Sprite) buttonSprites.get(i)).setTouchScreenListener(this);
      x1 += buttonImage.getWidth() + BUTTON_DISTANCE_HORIZONTAL;
    }
    updateFocus();
  }

  private void createVerticalButtons() {
    if (buttonLabels == null) {
      return;
    }
    int topY = alertY + 65;
    int y1 = topY;
    buttonSprites = ObjectArray.create(buttonLabels.len());
    for (int i = 0; i < buttonLabels.len(); i++) {
      buttonSprites.set(i, new Sprite(buttonImage, _manager, GameConstants.SCREEN_WIDTH / 2, y1, GameConstants.TOP_HCENTER_ANCHOR));
      final int index = i;
      ((Sprite) buttonSprites.get(i)).setDrawListener(new DrawListener() {
        public void paint(Sprite source, Graphics g) {
          vnText.drawString2(g, buttonLabels.get(index), GameColor.WHITE_CODE, GameConstants.SCREEN_WIDTH / 2, source.getRealY() + buttonImage.getHeight() / 2, GameConstants.CENTER_ANCHOR);
        }
      });
      ((Sprite) buttonSprites.get(i)).setTouchScreenListener(this);
      y1 += buttonImage.getHeight() + BUTTON_DISTANCE_VERTICAL;
    }
    updateFocus();
  }

  public void pointerDragged(Sprite source, int x1, int y1) {
  }

  public void pointerPressed(Sprite source, int x1, int y1) {
  }

  public void pointerReleased(Sprite source, int x1, int y1) {
    if (buttonLabels == null) {
      return;
    }

    for (int i = 0; i < buttonSprites.len(); i++) {
      if (source == buttonSprites.get(i)) {
        buttonIndex = i;
        break;
      }
    }
    updateFocus();
    executeEvent();
  }

  /**
   * Thiết lập số % hiện tại của loading Alert, nếu đạt 100% thì loading Alert sẽ tự động callback lại hàm alertEventPerform của State
   * 
   * @param loadingPercent - Số % hiện tại
   */
  public void setLoadingPercent(int loadingPercent) {
    if (loadingPercent >= 100) {
      if (parent != null) {
        parent.alertEventPerform(alertType, LOADING_DONE_EVENT, alertId);
      }
    }
  }

  public void setAutoHideInEvent(boolean isAutoHideInEvent1) {
    this.isAutoHideInEvent = isAutoHideInEvent1;
  }

  public int getAlertTimeOut() {
    return alertTimeOut;
  }

  public GameAlert setAlertTimeOut(int alertTimeOut1) {
    this.alertTimeOut = alertTimeOut1 / GameGlobal.systemCanvas.getTimer().getDelay();
    return this;
  }

  private void updateFocus() {
    if (buttonSprites != null) {
      for (int i = 0; i < buttonSprites.len(); i++) {
        if (i == buttonIndex) {
          ((Sprite) buttonSprites.get(i)).setImage(focusedButtonImage);
        } else {
          ((Sprite) buttonSprites.get(i)).setImage(buttonImage);
        }
      }
    }
  }

  public void keyReleased(int keyCode) {
    if (alertType == CUSTOM_UI_TYPE) {
      customeUI.doKeyReleased(keyCode);
      return;
    }

    if ((buttonLabels == null) || (buttonLabels.len() == 0)) {
      return;
    }

    switch (keyCode) {
    case Key.UP:
      buttonIndex--;
      if (buttonIndex < 0) {
        buttonIndex = (byte) (buttonLabels.len() - 1);
      }
      updateFocus();
      break;
    case Key.DOWN:
      buttonIndex++;
      buttonIndex = (byte) (buttonIndex % buttonLabels.len());
      updateFocus();
      break;
    case Key.LEFT:
      buttonIndex--;
      if (buttonIndex < 0) {
        buttonIndex = (byte) (buttonLabels.len() - 1);
      }
      updateFocus();
      break;
    case Key.RIGHT:
      buttonIndex++;
      buttonIndex = (byte) (buttonIndex % buttonLabels.len());
      updateFocus();
      break;
    case Key.FIRE:
      executeEvent();
      break;
    case Key.SOFT_RIGHT:
      String str = String.valueOf(alertId);
      if (str.length() < 2) {
        alertId = 0;
      } else {
        alertId = NumberUtil.parseInt(str.substring(0, str.length() - 1));
      }
      break;
    default:
      if (alertType == INPUT_NUMBER_TYPE) {
        if ((Key.K_0 <= keyCode) && (keyCode <= Key.K_9)) {
          int value = keyCode - Key.K_0;
          if (alertId == 0) {
            alertId = value;
          } else if (String.valueOf(alertId).length() < MAX_NUMBER_LEN) {
            alertId = NumberUtil.parseInt(alertId + String.valueOf(value));
          }
        }
      }
      break;
    }
  }

  private void executeEvent() {
    if (listenner == null) {
      GameGlobal.systemCanvas.hideAlert();
      return;
    }
    if (isAutoHideInEvent) {
      GameGlobal.systemCanvas.hideAlert();
    }
    switch (alertType) {
    case OK_TYPE:
      listenner.alertEventPerform(alertType, OK_BUTTON, alertId);
      break;
    case YES_NO_TYPE:
      switch (buttonIndex) {
      case 0:
        listenner.alertEventPerform(alertType, YES_BUTTON, alertId);
        break;
      case 1:
        listenner.alertEventPerform(alertType, NO_BUTTON, alertId);
        break;
      }
      break;
    case LOADING_WITH_CANCEL_BUTTON_TYPE:
      listenner.alertEventPerform(alertType, CANCEL_BUTTON, alertId);
      break;
    case CUSTOM_BUTTON_TYPE:
      listenner.alertEventPerform(alertType, buttonIndex, alertId);
      break;
    case INPUT_NUMBER_TYPE:
      listenner.alertEventPerform(alertType, buttonIndex, alertId);
      break;
    }
  }

  public void keyPressed(int keyCode) {
    if (alertType == CUSTOM_UI_TYPE) {
      customeUI.doKeyPressed(keyCode);
      return;
    }
  }

  public void keyRepeated(int keyCode) {
    if (alertType == CUSTOM_UI_TYPE) {
      customeUI.doKeyRepeated(keyCode);
      return;
    }
  }

  public void mouseMoved(int x1, int y1) {
    if (alertType == CUSTOM_UI_TYPE) {
      customeUI.doMouseMoved(x1, y1);
      return;
    }
  }

  public void mousePressed(int x1, int y1) {
    if (alertType == CUSTOM_UI_TYPE) {
      customeUI.doMousePressed(x1, y1);
      return;
    }
  }

  public void mouseReleased(int x1, int y1) {
    if (alertType == CUSTOM_UI_TYPE) {
      customeUI.doMouseReleased(x1, y1);
      return;
    }
  }

  public void onPointerDragged(int x1, int y1) {
    if (alertType == CUSTOM_UI_TYPE) {
      customeUI.doPointerDragged(x1, y1);
      return;
    }
  }

  public void onPointerPressed(int x1, int y1) {
    if (alertType == CUSTOM_UI_TYPE) {
      customeUI.doPointerPressed(x1, y1);
      return;
    }
  }

  public void onPointerReleased(int x1, int y1) {
    if (alertType == CUSTOM_UI_TYPE) {
      customeUI.doPointerReleased(x1, y1);
      return;
    }
  }

  public void destroy() {
    if ((alertType == CUSTOM_UI_TYPE) && (listenner != null)) {
      listenner.alertEventPerform(alertType, GameAlert.OK_BUTTON, alertId);
    }

    if (buttonSprites != null) {
      for (int i = 0; i < buttonSprites.len(); i++) {
        if (buttonSprites.get(i) != null) {
          ((Sprite) buttonSprites.get(i)).detroy();
          buttonSprites.set(i, null);
        }
      }
      buttonSprites = null;
    }

    removeTimerListener();
    if (customeUI != null) {
      customeUI.isRunning = false;
      customeUI = null;
    }
    alertTimeOut = Integer.MAX_VALUE;
    isRunning = false;
    parent = null;
    alertMessages.removeAllElements();
    buttonLabels = null;
  }
}
